#ifndef TRANSFORMERCONTENTTHREADPOOL_HPP_3
#define TRANSFORMERCONTENTTHREADPOOL_HPP_3

#include "logger.hpp"
#include "transContentIThreadRun.hpp"

typedef void* (*work)(void*);

struct Task{
	work iWork;
	void* iParam;
};

class TransContentThreadPool{
	private:
		int mThreadCount;
		int mState;
		int mWrokCount;
		int mtaskListCapacity;
		Task* taskList;
		pthread_t* threads;
		pthread_mutex_t poolMutex;
		pthread_cond_t poolCondtion;
		pthread threadCheck;
		static TransContentThreadPool* _instance;
	public:

		static TransContentThreadPool* getInstance(){
			debug_enter();
			if(_instance == NULL){
				logd_info("construct, create the thread pool instance");
				_instance = new TransContentThreadPool();
			}
			debug_leave();
			return _instance;
		}

		static void releaseInstance(){
			debug_enter();
			if(_instance != NULL){
				delete _instance;
				_instance = NULL;
			}
			debug_leave();
		}

		int start(){
			return createThreads();
		}

		int addTask(Task insTask);
		int addTask(work iwork, void* p);

		// p is this instance 
		int removeTask(void *p);

	private:
		int createThreads();

		int destroyThreads();

		/// this method must call in inroute, between mutex
		Task getATask(){
			Task iTask;
			iTask.iWork = NULL;
			iTask.iParam = NULL;
			debug_enter();
			for(int i=0; i< mtaskListCapacity; ++i){
				if(taskList[i].iWork != NULL){
					iTask = taskList[i];
					taskList[i].iWork = NULL;
					taskList[i].iParam = NULL;
					--mWrokCount;
				}
			}
			debug_leave();
			return iTask;
		}


		TransContentThreadPool():mThreadCount(THREADS_COUNT_DEFAULT), mState(INS_STATE_ERROR),mWrokCount(0), mtaskListCapacity(THREAD_TASK_COUNT_DEFAULT), taskList(NULL), threads(NULL), poolMutex(PTHREAD_MUTEX_INITIALIZER), poolCondtion(PTHREAD_COND_INITIALIZER){
			debug_enter();
			taskList = (Task*)calloc(mtaskListCapacity, sizeof(Task));
			threads = (pthread_t*)calloc(mThreadCount, sizeof(pthread_t));
			debug_leave();
		}

		virtual ~TransContentThreadPool(){
			debug_enter();
			mState = INS_STATE_ERROR;
			destroyThreads();
			if(taskList != NULL){
				delete taskList;
				taskList = NULL;
			}
			if(threads != NULL){
				delete threads;
				threads = NULL;
			}
			debug_leave();
		}

		static void* threadRoute(void* p){
			debug_enter();
			((TransContentThreadPool*)(p))->threadRouteIns();
			debug_leave();
		};

		static void* threadCheckRoute(void* p){
			 debug_enter();
			 ((TransContentThreadPool*)(p))->threadCheckRouteIns();
			 debug_leave();
		}

		void threadCheckRouteIns();
		void threadRouteIns();
}
#endif //TRANSFORMERCONTENTTHREADPOOL_HPP_3
